home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / AvantBrowser / asetup.exe / _data / webkit / resources.pak / Unnamed File 000053.txt < prev    next >
Text File  |  2013-04-03  |  7KB  |  242 lines

  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4.  
  5. cr.define('cr.ui', function() {
  6.   /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
  7.   /** @const */ var List = cr.ui.List;
  8.   /** @const */ var ListItem = cr.ui.ListItem;
  9.  
  10.   /**
  11.    * Creates a new autocomplete list item.
  12.    * @param {Object} pageInfo The page this item represents.
  13.    * @constructor
  14.    * @extends {cr.ui.ListItem}
  15.    */
  16.   function AutocompleteListItem(pageInfo) {
  17.     var el = cr.doc.createElement('div');
  18.     el.pageInfo_ = pageInfo;
  19.     AutocompleteListItem.decorate(el);
  20.     return el;
  21.   }
  22.  
  23.   /**
  24.    * Decorates an element as an autocomplete list item.
  25.    * @param {!HTMLElement} el The element to decorate.
  26.    */
  27.   AutocompleteListItem.decorate = function(el) {
  28.     el.__proto__ = AutocompleteListItem.prototype;
  29.     el.decorate();
  30.   };
  31.  
  32.   AutocompleteListItem.prototype = {
  33.     __proto__: ListItem.prototype,
  34.  
  35.     /** @override */
  36.     decorate: function() {
  37.       ListItem.prototype.decorate.call(this);
  38.  
  39.       var title = this.pageInfo_['title'];
  40.       var url = this.pageInfo_['displayURL'];
  41.       var titleEl = this.ownerDocument.createElement('span');
  42.       titleEl.className = 'title';
  43.       titleEl.textContent = title || url;
  44.       this.appendChild(titleEl);
  45.  
  46.       if (title && title.length > 0 && url != title) {
  47.         var separatorEl = this.ownerDocument.createTextNode(' - ');
  48.         this.appendChild(separatorEl);
  49.  
  50.         var urlEl = this.ownerDocument.createElement('span');
  51.         urlEl.className = 'url';
  52.         urlEl.textContent = url;
  53.         this.appendChild(urlEl);
  54.       }
  55.     },
  56.   };
  57.  
  58.   /**
  59.    * Creates a new autocomplete list popup.
  60.    * @constructor
  61.    * @extends {cr.ui.List}
  62.    */
  63.   var AutocompleteList = cr.ui.define('list');
  64.  
  65.   AutocompleteList.prototype = {
  66.     __proto__: List.prototype,
  67.  
  68.     /**
  69.      * The text field the autocomplete popup is currently attached to, if any.
  70.      * @type {HTMLElement}
  71.      * @private
  72.      */
  73.     targetInput_: null,
  74.  
  75.     /**
  76.      * Keydown event listener to attach to a text field.
  77.      * @type {Function}
  78.      * @private
  79.      */
  80.     textFieldKeyHandler_: null,
  81.  
  82.     /**
  83.      * Input event listener to attach to a text field.
  84.      * @type {Function}
  85.      * @private
  86.      */
  87.     textFieldInputHandler_: null,
  88.  
  89.     /**
  90.      * A function to call when new suggestions are needed.
  91.      * @type {Function}
  92.      * @private
  93.      */
  94.     suggestionUpdateRequestCallback_: null,
  95.  
  96.     /** @override */
  97.     decorate: function() {
  98.       List.prototype.decorate.call(this);
  99.       this.classList.add('autocomplete-suggestions');
  100.       this.selectionModel = new cr.ui.ListSingleSelectionModel;
  101.  
  102.       this.textFieldKeyHandler_ = this.handleAutocompleteKeydown_.bind(this);
  103.       var self = this;
  104.       this.textFieldInputHandler_ = function(e) {
  105.         if (self.suggestionUpdateRequestCallback_)
  106.           self.suggestionUpdateRequestCallback_(self.targetInput_.value);
  107.       };
  108.       this.addEventListener('change', function(e) {
  109.         var input = self.targetInput;
  110.         if (!input || !self.selectedItem)
  111.           return;
  112.         input.value = self.selectedItem['url'];
  113.         // Programatically change the value won't trigger a change event, but
  114.         // clients are likely to want to know when changes happen, so fire one.
  115.         var changeEvent = document.createEvent('Event');
  116.         changeEvent.initEvent('change', true, true);
  117.         input.dispatchEvent(changeEvent);
  118.       });
  119.       // Start hidden; adding suggestions will unhide.
  120.       this.hidden = true;
  121.     },
  122.  
  123.     /** @override */
  124.     createItem: function(pageInfo) {
  125.       return new AutocompleteListItem(pageInfo);
  126.     },
  127.  
  128.     /**
  129.      * The suggestions to show.
  130.      * @type {Array}
  131.      */
  132.     set suggestions(suggestions) {
  133.       this.dataModel = new ArrayDataModel(suggestions);
  134.       this.hidden = !this.targetInput_ || suggestions.length == 0;
  135.     },
  136.  
  137.     /**
  138.      * A function to call when the attached input field's contents change.
  139.      * The function should take one string argument, which will be the text
  140.      * to autocomplete from.
  141.      * @type {Function}
  142.      */
  143.     set suggestionUpdateRequestCallback(callback) {
  144.       this.suggestionUpdateRequestCallback_ = callback;
  145.     },
  146.  
  147.     /**
  148.      * Attaches the popup to the given input element. Requires
  149.      * that the input be wrapped in a block-level container of the same width.
  150.      * @param {HTMLElement} input The input element to attach to.
  151.      */
  152.     attachToInput: function(input) {
  153.       if (this.targetInput_ == input)
  154.         return;
  155.  
  156.       this.detach();
  157.       this.targetInput_ = input;
  158.       this.style.width = input.getBoundingClientRect().width + 'px';
  159.       this.hidden = false;  // Necessary for positionPopupAroundElement to work.
  160.       cr.ui.positionPopupAroundElement(input, this, cr.ui.AnchorType.BELOW);
  161.       // Start hidden; when the data model gets results the list will show.
  162.       this.hidden = true;
  163.  
  164.       input.addEventListener('keydown', this.textFieldKeyHandler_, true);
  165.       input.addEventListener('input', this.textFieldInputHandler_);
  166.     },
  167.  
  168.     /**
  169.      * Detaches the autocomplete popup from its current input element, if any.
  170.      */
  171.     detach: function() {
  172.       var input = this.targetInput_;
  173.       if (!input)
  174.         return;
  175.  
  176.       input.removeEventListener('keydown', this.textFieldKeyHandler_, true);
  177.       input.removeEventListener('input', this.textFieldInputHandler_);
  178.       this.targetInput_ = null;
  179.       this.suggestions = [];
  180.     },
  181.  
  182.     /**
  183.      * Makes sure that the suggestion list matches the width of the input it is.
  184.      * attached to. Should be called any time the input is resized.
  185.      */
  186.     syncWidthToInput: function() {
  187.       var input = this.targetInput_;
  188.       if (input)
  189.         this.style.width = input.getBoundingClientRect().width + 'px';
  190.     },
  191.  
  192.     /**
  193.      * @return {HTMLElement} The text field the autocomplete popup is currently
  194.      *     attached to, if any.
  195.      */
  196.     get targetInput() {
  197.       return this.targetInput_;
  198.     },
  199.  
  200.     /**
  201.      * Handles input field key events that should be interpreted as autocomplete
  202.      * commands.
  203.      * @param {Event} event The keydown event.
  204.      * @private
  205.      */
  206.     handleAutocompleteKeydown_: function(event) {
  207.       if (this.hidden)
  208.         return;
  209.       var handled = false;
  210.       switch (event.keyIdentifier) {
  211.         case 'U+001B':  // Esc
  212.           this.suggestions = [];
  213.           handled = true;
  214.           break;
  215.         case 'Enter':
  216.           // If the user has already selected an item using the arrow keys then
  217.           // presses Enter, clear the suggestions but also keep
  218.           // |handled| = false, so the input field can handle the event as well.
  219.           this.suggestions = [];
  220.           break;
  221.         case 'Up':
  222.         case 'Down':
  223.           var newEvent = new cr.Event(event.type);
  224.           newEvent.keyIdentifier = event.keyIdentifier;
  225.           this.dispatchEvent(newEvent);
  226.           handled = true;
  227.           break;
  228.       }
  229.       // Don't let arrow keys affect the text field, or bubble up to, e.g.,
  230.       // an enclosing list item.
  231.       if (handled) {
  232.         event.preventDefault();
  233.         event.stopPropagation();
  234.       }
  235.     },
  236.   };
  237.  
  238.   return {
  239.     AutocompleteList: AutocompleteList
  240.   };
  241. });
  242.